#pragma once
#include <sys/epoll.h>
#include <functional>   //函数对象的头文件
#include "InetAddress.h"
#include "Socket.h"
#include "EventLoop.h"
#include <memory>

class EventLoop;

class Channel
{
private:
    int fd_ = -1;               //Channel拥有的fd,Channel和fd是一对一的关系。
    EventLoop* loop_;       //Channel对应的红黑树，Channel与EventLoop是多对一的关系，一个Channel只对应一个EventLoop
    bool inepoll_ = false;      //Channel是否已添加到epoll树上，如果未添加，调用epoll_ctl()的时候调用EPOLL_CTL_ADD，否则用EPOLL_CTL_MOD。
    uint32_t events_ = 0;       //fd_需要监视的事件。listenfd和clientfd需要监视EPOLLIN,clientfd还可能需要监视EPOLLOUT
    uint32_t revents_ = 0;      //fd_已发生的事件。
    std::function<void()> read_CallBack_;    //fd_读事件的回调函数，在创建时绑定
    std::function<void()> close_CallBack_;   //关闭fd_的回调函数，将回调Connection::closeCallBack
    std::function<void()> error_CallBack_;   //fd_发生了错误的回调函数，将回调Connection::errorCalBack()
    std::function<void()> write_CallBack_;   //fd_写事件的回调函数，将回调Connection::witeCallback()
public:
    Channel(EventLoop* loop, int fd);      //构造函数
    ~Channel();                     //析构函数

    int fd();                       //返回fd成员
    void useet();                   //采用边缘触发
    void enable_Reading();           //让epoll_wait()监视fd_的读事件
    void disable_Reading();         //取消读事件
    void enbale_Writing();          //注册写事件
    void disable_Writing();         //取消写事件
    void disable_All();             //取消全部的事件
    void remove();                  //从事件循环中删除channel
    void setinepoll();              //把inepoll_成员的值设置为true
    void setrevents(uint32_t ev);   //把revents_成员的值设置为参数ev
    bool inpoll();                  //返回inepoll成员
    uint32_t events();              //返回events_成员
    uint32_t revents();             //返回revents_成员

    void handle_Event();            //事件处理函数，epoll返回的时候处理
    //void on_Message();                              //处理对端发来的消息
    
    void set_Read_CallBack(std::function<void()> func);     //设置fd_读事件的回调函数
    void set_Close_CallBack(std::function<void()> func);
    void set_Error_CallBack(std::function<void()> func);
    void set_Write_CallBack(std::function<void()> func);
};